iT邦幫忙

2022 iThome 鐵人賽

DAY 21
0

https://ithelp.ithome.com.tw/upload/images/20220912/20151958IFjRs0xIZ4.png Medium 好讀版

此系列文章是以我的業餘專案: Kimoji 作為範例。
這款以純 Jetpack Compose 撰寫的 side project,已經在 Google Play 上架。 歡迎試玩!

https://ithelp.ithome.com.tw/upload/images/20220907/20151958vXuPLv4aki.png 立馬下載

昨天的文章中,因為我們已經將日記清單 hoist 到 screen level,所以我們可以修改 Journal composable function,來移除日記清單的 default parameter。接著再新增一個 lambda 函式參數 onDelete (接收要刪除的 Diary)。然後把 onDelete 傳遞至 Diary

@Composable
fun Journal(
   modifier: Modifier = Modifier,
   diaries: List<Diary>,
   onDelete: (Diary) -> Unit
) {
   LazyColumn(modifier = modifier) {
       items(
           items = diaries,
           key = { diary -> diary.id }
       ) { task ->
           Diary(notes = diary.notes, onDelete = { onDelete(diary) })
       }
   }
}

在上面的程式碼中,items 方法會收到 key 參數。根據預設,每個 item 的狀態都會與 item 在清單中的位置對應。

在 mutable list 的資料內容有變時,這樣就會發生問題,因為變更位置的 item 就等同於喪失 remember 的狀態。

因此我們可以使用每個 Diaryid 當做每個 item 的 key,就能輕鬆解決問題。

如果想進一步瞭解清單中的 item keys,請看官方說明文件。

接著定義一個 stateful Diary composable:加入 onDelete lambda 函式作為 Diary 的參數並進行呼叫。

@Composable
fun Diary(
   modifier: Modifier = Modifier,
   notes: String, 
   onDelete: () -> Unit
) {
   var checkedState by rememberSaveable { mutableStateOf(false) }

   Diary(
       modifier = modifier,
       notes = notes,
       checked = checkedState,
       onCheckedChange = { newValue -> checkedState = newValue },
       onDelete = onDelete
   )
}

現在這個功能已經完成,現在可以從日記清單中刪除項目了。

只要按下每一篇日記上的「刪除」,事件會往上傳遞到持有該狀態的日記清單,然後移除清單內的日記,並觸發 Compose recompose 畫面。

如果我們嘗試使用 rememberSaveable()DiaryScreen 裡面儲存清單,就會發生 runtime exception:

cannot be saved using the current SaveableStateRegistry. The default implementation only supports types which can be stored inside the Bundle. Please consider implementing a custom Saver for this class and pass it to rememberSaveable().

這個錯誤說明我們需要提供 custom saver。但是,最好不要使用 rememberSaveable 儲存需要長時間 serialize 或 deserialize 的大量資料或複雜的資料結構。

當使用 ActivityonSaveInstanceState 時,也需要遵守一樣的規定,詳情請參閱儲存 UI 狀態說明文件。如果要實現這個需求,需要採用其他儲存機制。可以參閱官方說明文件,瞭解其他的保留 UI 狀態方法

接下來幾天,我們要瞭解 ViewModel 在 state holder 方面扮演的角色

此系列文章是以我的業餘專案:Kimoji 為範例。

Kimoji 是一款心情日記 App,讓你用可愛的 emoji 來撰寫你的心情日記。現在就來試試這款設計精美的微日記吧!

https://ithelp.ithome.com.tw/upload/images/20220907/20151958vXuPLv4aki.png 立馬下載

Reference: https://developer.android.com/codelabs/jetpack-compose-state


上一篇
可觀察的 MutableList
下一篇
ViewModel 中的狀態
系列文
Kimoji:以 Jetpack Compose 實作一款「心情日記」應用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言